﻿using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Ortodoctor.modelo
{
    public class Servico : conexao
    {
        public bool verificaPrimeiroAcessoDia()
        {
            bool fechou = false;
            //conexao con = new conexao();

            conn = new NpgsqlConnection(connectionstring);
            conn.Open();
            DataTable dt = new DataTable();
            //con.open();'
            String sql = "select valor from configuracoes where parametro = 'ultima_data'";
            NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
            da.Fill(dt);
            conn.Close();

            string hoje = DateTime.Now.ToString("dd/MM/yyyy");
            
            string data = dt == null || dt.Rows.Count == 0 ? hoje : dt.Rows[0]["valor"].ToString();

            if (hoje.Equals(data))
            {
                fechou = true;
            }

            if (!fechou)
            {
                conn.Open();
                DataTable dt1 = new DataTable();

                sql = @"with parcela as(select *
                            from parcelas
                            where data_vencimento > (now() - interval '1 MONTH') AND DATA_VENCIMENTO < NOW() )

                            select id_cliente, id_procedimento_cliente, id_parcela from procedimento_cliente
                            inner join parcela using(id_procedimento_cliente) WHERE DATA_VENCIMENTO < NOW()";
                da = new NpgsqlDataAdapter(sql, conn);
                da.Fill(dt1);
                conn.Close();

                conn.Open();
                sql = "update configuracoes set valor = '" + hoje + "' where parametro = 'ultima_data' ";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.ExecuteNonQuery();
                conn.Close();

                DateTime dtime = Convert.ToDateTime(data);

                dtime = dtime.AddDays(-1);

                conn.Open();
                dt = new DataTable();
                sql = "select * from parcelas where data_vencimento <= '" + dtime.ToString("MM/dd/yyyy") + "' and status ='EM DIA'";
                da = new NpgsqlDataAdapter(sql, conn);
                try
                {
                    da.Fill(dt);
                }
                catch
                {
                }
                conn.Close();

                conn.Open();
                sql = "update parcelas set status = 'ATRASADA' where data_vencimento <= '" + dtime.ToString("MM/dd/yyyy") + "' and status ='EM DIA'";

                com = new NpgsqlCommand(sql, conn);
                com.ExecuteNonQuery();
                conn.Close();

                int cont = 0;
                int dia = 0;

                if (!string.IsNullOrEmpty(data)
                    && Convert.ToDateTime(data).Month != Convert.ToDateTime(hoje).Month)
                {
                    string DataBase = DateTime.Now.AddDays(DateTime.Now.Day -1 ).ToString("MM/dd/yyyy");

                    conn.Open();
                    sql = @"SELECT * FROM PARCELAS INNER JOIN PROCEDIMENTO_CLIENTE USING(ID_PROCEDIMENTO_CLIENTE) WHERE DATA_VENCIMENTO > (DATE('" + DataBase +"') - INTERVAL '1 MONTH') AND DATA_VENCIMENTO < DATE('" + DataBase + @"') 
                        AND ID_CLIENTE NOT IN (SELECT ID_CLIENTE FROM COMPARECIMENTO WHERE DATA > (DATE('" + DataBase +"') - INTERVAL '1 MONTH') AND DATA_VENCIMENTO < DATE('" + DataBase +"')) AND PARCELAS.STATUS = 'ATRASADA'";

                    da = new NpgsqlDataAdapter(sql, conn);
                    try
                    {
                        da.Fill(dt);
                    }
                    catch(Exception ex)
                    {
                    }
                    conn.Close();

                    conn.Open();
                    dt1 = new DataTable();

                    sql = @"with parcela as(select *
                            from parcelas
                            where data_vencimento > (DATE('" + DataBase + "') - interval '1 MONTH') AND DATA_VENCIMENTO < DATE('" + DataBase + @"') )

                            select id_cliente, id_procedimento_cliente, id_parcela from procedimento_cliente
                            inner join parcela using(id_procedimento_cliente) WHERE DATA_VENCIMENTO < DATE('" + DataBase + "')";
                    da = new NpgsqlDataAdapter(sql, conn);
                    da.Fill(dt1);
                    conn.Close();


                    foreach (DataRow dr in dt.Rows)
                    {
                        dt1.DefaultView.RowFilter = "[id_parcela]='" + dr["id_parcela"] + "'";
                        if (dt1.DefaultView.ToTable().Rows.Count > 0)
                        {
                            conn.Open();
                            sql = "update parcelas set status = 'TRANSFERIDA' where id_parcela=" + dt1.DefaultView.ToTable().Rows[0]["id_parcela"];
                            com = new NpgsqlCommand(sql, conn);
                            com.ExecuteNonQuery();
                            conn.Close();

                            conn.Open();
                            DataTable temp = new DataTable();
                            sql = "select max(data_vencimento) as data_maxima, id_procedimento_cliente from parcelas where id_procedimento_cliente = " + dr["id_procedimento_cliente"].ToString() + " group by id_procedimento_cliente";
                            da = new NpgsqlDataAdapter(sql, conn);
                            da.Fill(temp);
                            conn.Close();

                            DateTime datetime = Convert.ToDateTime(temp.Rows[0]["data_maxima"]);

                            dia = datetime.Day;
                            int mes = datetime.Month;
                            int ano = datetime.Year;
                            DateTime dateParcela = new DateTime();
                            for (int j = 0; j <= 5; ++j)
                            {
                                try
                                {
                                    if (cont == 1)
                                        cont++;
                                    else
                                        if (cont == 2)
                                        {
                                            mes--;
                                            ++cont;
                                        }
                                    dateParcela = Convert.ToDateTime((dia) + "/" + (++mes) + "/" + (ano));
                                    if (cont == 3)
                                        cont = 0;
                                    break;
                                }
                                catch
                                {
                                    if (mes > 12)
                                    {
                                        mes = 0;
                                        ano++;
                                    }
                                    else
                                    {
                                        dia = 1;
                                        ++cont;
                                    }
                                }
                            }
                            modeloParcelas parcelas = new modeloParcelas();
                            parcelas.insert(new Componentes.Parcelas(-1,
                                                                    Convert.ToDouble(dr["valor"]),
                                                                    dateParcela,
                                                                    Convert.ToInt32(dr["id_procedimento_cliente"]),
                                                                    "EM DIA"));

                        }
                        conn.Close();

                    }
                }

                DataTable clienteCredito = new DataTable();
                conn.Open();
                sql = @"SELECT ID_CLIENTE, CREDITO FROM CLIENTE INNER JOIN CREDITOS USING(ID_CLIENTE)";

                da = new NpgsqlDataAdapter(sql, conn);
                try
                {
                    da.Fill(clienteCredito);
                }
                catch
                {
                }
                conn.Close();
                foreach (DataRow dr in clienteCredito.Rows)
                {
                    calculaCreditos(Convert.ToInt32(dr["ID_CLIENTE"]), Convert.ToInt32(dr["CREDITO"]));
                }

            }

            modeloComparecimento model = new modeloComparecimento();
            return model.getMaxDate();
        }

        public static string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, format);
                byte[] imageBytes = ms.ToArray();

                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }

        public static Image Base64ToImage(string base64String)
        {
            // Convert Base64 String to byte[]
            byte[] imageBytes = Convert.FromBase64String(base64String);
            MemoryStream ms = new MemoryStream(imageBytes, 0,
              imageBytes.Length);

            // Convert byte[] to Image
            ms.Write(imageBytes, 0, imageBytes.Length);
            Image image = Image.FromStream(ms, true);
            return image;
        }

        public static void calculaCreditos(int id_cliente, int credito_cliente = 0)
        {
            conexao con = new conexao();

            con.conn = new NpgsqlConnection(con.connectionstring);
            con.conn.Open();
            DataTable dtCliente = new DataTable();
            String sql = @"SELECT PARCELAS.* FROM CLIENTE INNER JOIN 
	                                  PROCEDIMENTO_CLIENTE USING(ID_CLIENTE) INNER JOIN
	                                  PARCELAS USING(ID_PROCEDIMENTO_CLIENTE) inner join
                                      procedimento using (id_procedimento)


                            WHERE ID_CLIENTE = " + id_cliente + " AND PROMOCAO = 'Sim' ORDER BY DATA_VENCIMENTO";
            NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, con.conn);
            da.Fill(dtCliente);
            con.conn.Close();
            con.conn.Open();
            DataTable dtIndicados = new DataTable();
            sql = @"SELECT DISTINCT PARCELAS.* FROM INDICADO INNER JOIN
     		                           PROCEDIMENTO_CLIENTE ON ID_CLIENTE_INDICADO = PROCEDIMENTO_CLIENTE.ID_CLIENTE INNER JOIN
     		                           PARCELAS USING(ID_PROCEDIMENTO_CLIENTE) inner join 
                                       procedimento using (id_procedimento)
                    WHERE ID_CLIENTE_INDICOU = " + id_cliente + " AND PROMOCAO = 'Sim' ORDER BY DATA_VENCIMENTO";
            da = new NpgsqlDataAdapter(sql, con.conn);
            da.Fill(dtIndicados);
            con.conn.Close();

            long cont = 0;
            string pareEm = "";
            foreach (DataRow dr in dtCliente.Rows)
            {
                if (dr["STATUS"].ToString().ToUpper().Equals("ATRASADA"))
                {
                    pareEm = "01/" + Convert.ToDateTime(dr["data_vencimento"]).ToString("MM/yyyy");
                    break;
                }
                if (dr["STATUS"].ToString().ToUpper().Contains("PAGO"))
                {
                    dtIndicados.DefaultView.RowFilter = "[data_vencimento] > '" + "01/" + Convert.ToDateTime(dr["data_vencimento"]).ToString("MM/yyyy") + @"' AND
                                                     [data_vencimento] <= '" + "01/" + Convert.ToDateTime(dr["data_vencimento"]).AddMonths(1).ToString("MM/yyyy") + @"' 
                                                     AND [STATUS] LIKE '%PAGO%'";
                    cont += Convert.ToInt32(dtIndicados.DefaultView.ToTable().Rows.Count / 2);
                }
            }

            dtIndicados.DefaultView.RowFilter = "";
            dtCliente.DefaultView.RowFilter = "[STATUS] = 'PAGO' OR [STATUS] = 'PAGO CLINICA'";
            dtCliente = dtCliente.DefaultView.ToTable();

            DataView DvCliente = dtCliente.DefaultView;
            DataTable distinctCliente = DvCliente.ToTable(true, "data_vencimento");

            DataView Dvdistinct = dtIndicados.DefaultView;
            DataTable distinct = Dvdistinct.ToTable(true, "data_vencimento");

            foreach (DataRow dr in distinctCliente.Rows)
            {
                DataRow[] drows = distinct.Select("[data_vencimento] > '" + "01/" + Convert.ToDateTime(dr["data_vencimento"]).ToString("MM/yyyy") + @"' AND
                                                   [data_vencimento] <= '" + "01/" + Convert.ToDateTime(dr["data_vencimento"]).AddMonths(1).ToString("MM/yyyy") + "'");

                foreach (DataRow drow in drows)
                {
                    distinct.Rows.Remove(drow);
                }
            }

            string mesAno = "";
            foreach (DataRow dr in distinct.Rows)
            {
                if (mesAno.Equals(Convert.ToDateTime(dr["data_vencimento"]).ToString("MM/yyyy")))
                    continue;

                if (string.IsNullOrEmpty(pareEm) ||
                    Convert.ToDateTime(dr["data_vencimento"]) < Convert.ToDateTime(pareEm))
                {
                    dtIndicados.DefaultView.RowFilter = "[data_vencimento] > '" + "01/" + Convert.ToDateTime(dr["data_vencimento"]).ToString("MM/yyyy") + @"' AND
                                                         [data_vencimento] <= '" + "01/" + Convert.ToDateTime(dr["data_vencimento"]).AddMonths(1).ToString("MM/yyyy") + @"' AND
                                                         [STATUS] LIKE '%PAGO%'"; 
                    cont += Convert.ToInt32(dtIndicados.DefaultView.ToTable().Rows.Count / 3);
                }
                mesAno = Convert.ToDateTime(dr["data_vencimento"]).ToString("MM/yyyy");
            }

            if (cont * 40 != credito_cliente)
            {
                new modeloCredito().credita(Convert.ToInt32(cont * 40), id_cliente);
            }
        }
    }
}